{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Reaching multiple targets with a manipulator\n",
    "The objective of this exercise is to reach multiple targets with a manipulator.\n",
    "\n",
    "We provide a basic example for reaching one point, and you have to modify it for sequence of multiple targets. Below it is the basic example, there we'll guide you to the final result.\n",
    "\n",
    "本练习的目标是使用机械臂到达多个目标。\n",
    "\n",
    "我们提供了一个到达单个点的基本示例，你需要对其进行修改以实现多个目标的序列。以下是基本示例，我们将在此基础上引导你得出最终结果。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Set up"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "import magic_donotload"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will need crocoddyl as in the previous notebook, with the model of the arm of the humanoid robot Talos, a 7-dof arm. It can be found in example robot data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "import crocoddyl\n",
    "import pinocchio as pin\n",
    "import numpy as np\n",
    "import example_robot_data as robex"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The optimal-control program"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, let's load the Pinocchio model for the Talos arm."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "robot = robex.load('talos_arm')\n",
    "robot_model = robot.model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Set robot model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "robot_model.armature =np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.])*5  # It is a regularization of the mass matric M' = M + lamb I\n",
    "robot_model.q0 = np.array([3.5,2,2,0,0,0,0])\n",
    "robot_model.x0 = np.concatenate([robot_model.q0, np.zeros(robot_model.nv)])\n",
    "robot_model.gravity *= 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's add a viewer to display the model.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "You can open the visualizer by visiting the following URL:\n",
      "http://127.0.0.1:7004/static/\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "            <div style=\"height: 400px; width: 100%; overflow-x: auto; overflow-y: hidden; resize: both\">\n",
       "            <iframe src=\"http://127.0.0.1:7004/static/\" style=\"width: 100%; height: 100%; border: none\"></iframe>\n",
       "            </div>\n",
       "            "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from utils.meshcat_viewer_wrapper import MeshcatVisualizer\n",
    "viz = MeshcatVisualizer(robot)\n",
    "viz.display(robot_model.q0)\n",
    "viz.viewer.jupyter_cell()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "viz.addBox('world/goal',[.1,.1,.1],[0,1,0,1])\n",
    "viz.applyConfiguration('world/goal',[.2,.5,.5,0,0,0,1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Configure the task."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "FRAME_TIP = robot_model.getFrameId(\"gripper_left_fingertip_3_link\")  # Wrapper around pinocchio\n",
    "goal = np.array([.2,.5,.5])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a cost model per the running and terminal action model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "state = crocoddyl.StateMultibody(robot_model)\n",
    "# The state object containt info about the configspace, the constraint, the velocity, the kinematic values and everything\n",
    "\n",
    "# State is quite abstract, to have a real solvable OCP we need to define somme cost associated to this model\n",
    "# We also need to decide the actual dynamic we will follow (called actuation), it means a solver that will be ourf(x,u) AND a way to descretize it\n",
    "\n",
    "runningCostModel = crocoddyl.CostModelSum(state)  # The state will remain the same during running \n",
    "terminalCostModel = crocoddyl.CostModelSum(state)  # And also for final state"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that we need to include a cost model (i.e. set of cost functions) in order to fully define the action model for our optimal control problem.\n",
    "For this particular example, we formulate three running-cost functions: goal-tracking cost, state and control regularization; and a terminal cost: goal cost. First, let's create the common cost functions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Cost for 3d tracking || p(q) - pref ||**2\n",
    "goalTrackingRes = crocoddyl.ResidualModelFrameTranslation(state,FRAME_TIP,goal)\n",
    "goalTrackingCost = crocoddyl.CostModelResidual(state,goalTrackingRes)\n",
    "\n",
    "# Cost for 6d tracking  || log( M(q)^-1 Mref ) ||**2\n",
    "Mref = pin.SE3(pin.utils.rpyToMatrix(0,np.pi/2,-np.pi/2), goal)\n",
    "goal6TrackingRes = crocoddyl.ResidualModelFramePlacement(state,FRAME_TIP,Mref)\n",
    "goal6TrackingCost = crocoddyl.CostModelResidual(state,goal6TrackingRes)\n",
    "\n",
    "# Cost for state regularization || x - x* ||**2\n",
    "xRegWeights = crocoddyl.ActivationModelWeightedQuad(np.array([1,1,1,1,1,1,1, 1,1,1,1,2,2,2.]))\n",
    "xRegRes = crocoddyl.ResidualModelState(state,robot_model.x0)\n",
    "xRegCost = crocoddyl.CostModelResidual(state,xRegWeights,xRegRes)\n",
    "\n",
    "# Cost for control regularization || u - g(q) ||**2\n",
    "uRegRes = crocoddyl.ResidualModelControlGrav(state)\n",
    "uRegCost = crocoddyl.CostModelResidual(state,uRegRes)\n",
    "\n",
    "# Terminal cost for state regularization || x - x* ||**2\n",
    "xRegWeightsT=crocoddyl.ActivationModelWeightedQuad(np.array([1,1,1,1,1,1,1, 1,1,1,1,2,2,2.]))\n",
    "xRegResT = crocoddyl.ResidualModelState(state,robot_model.x0)\n",
    "xRegCostT = crocoddyl.CostModelResidual(state,xRegWeightsT,xRegResT)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then let's added the running and terminal cost functions and the constant weight for each whole cost"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "runningCostModel.addCost(\"gripperPose\", goalTrackingCost, .001)  # addCost is a method of CostModelSum that take another CostModel\n",
    "runningCostModel.addCost(\"xReg\", xRegCost, 1e-3)  # We also weight the sum of cost\n",
    "runningCostModel.addCost(\"uReg\", uRegCost, 1e-6)\n",
    "terminalCostModel.addCost(\"gripperPose\", goalTrackingCost, 10)\n",
    "terminalCostModel.addCost(\"xReg\", xRegCostT, .01)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we need to create an action model for running and terminal knots. The\n",
    "forward dynamics (computed using ABA) are implemented inside DifferentialActionModelFullyActuated."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "actuationModel = crocoddyl.ActuationModelFull(state)\n",
    "dt = 1e-2\n",
    "# A step in the running step\n",
    "## We use the freefall forward dynamic as dotx = f(x,u) it could be a contact one (as in prev TP) and so on\n",
    "### It is the differential model chosen around the state\n",
    "## We precise the duration of the step dt\n",
    "## We precise the integration scheme we use \n",
    "### It is the integrated model chosen around the differential model\n",
    "## We precise which cost is used during this step\n",
    "runningModel = crocoddyl.IntegratedActionModelEuler(\n",
    "    crocoddyl.DifferentialActionModelFreeFwdDynamics(state, actuationModel, runningCostModel), dt)\n",
    "runningModel.differential.armature = robot_model.armature\n",
    "\n",
    "\n",
    "terminalModel = crocoddyl.IntegratedActionModelEuler(\n",
    "    crocoddyl.DifferentialActionModelFreeFwdDynamics(state, actuationModel, terminalCostModel), 0.)\n",
    "terminalModel.differential.armature = robot_model.armature"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For this optimal control problem, we define 250 knots (or running action\n",
    "models) plus a terminal knot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "T = 100\n",
    "problem = crocoddyl.ShootingProblem(robot_model.x0, [runningModel] * T, terminalModel)\n",
    "# We chain all the discrete step with their cost from an initial value even the final one that have the terminal costs\n",
    "# We just repeat the running step for a number of time and add the terminal node\n",
    "## This problem object contain discretized dynamic and cost on horizon T for a state (aka a system)\n",
    "### Alternative could have be variable actuaction type, e.g. to force sequence of contact\n",
    "### other integration...\n",
    "### Other type of problem like multiple shooting, colocation...\n",
    "# Problem is an OCP problem formulation !"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We finalize the set up by creating the DDP solver for this optimal control problem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "# We wrap the problem into a solver (an algorithm method to solve OCP)\n",
    "ddp = crocoddyl.SolverDDP(problem)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Callbacks can be added, for example to at verbose output when the solver runs, or logs the data of the descent algorithm."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [],
   "source": [
    "ddp.setCallbacks([\n",
    "    crocoddyl.CallbackLogger(),\n",
    "    crocoddyl.CallbackVerbose(),\n",
    "])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The DDP algorithm is run by the solver with:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "iter    cost       merit      stop       grad       preg       dreg      step   ||ffeas||  ||gfeas||  ||hfeas||   dV-exp       dV      dPhi-exp     dPhi\n",
      "   0  4.556e+00  0.000e+00  4.741e+00  9.483e+00  1.000e-09  1.000e-09  1.0000  3.500e+00  0.000e+00  0.000e+00  4.741e+00  3.860e+00  0.000e+00  0.000e+00\n",
      "   1  1.041e+00  0.000e+00  4.368e+00  8.737e+00  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  4.368e+00  3.516e+00  0.000e+00  0.000e+00\n",
      "   2  3.361e-01  0.000e+00  9.285e-01  1.857e+00  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  9.285e-01  7.044e-01  0.000e+00  0.000e+00\n",
      "   3  2.435e-01  0.000e+00  3.116e-01  6.232e-01  1.000e-09  1.000e-09  0.2500  0.000e+00  0.000e+00  0.000e+00  1.363e-01  9.262e-02  0.000e+00  0.000e+00\n",
      "   4  1.698e-01  0.000e+00  2.208e-01  4.415e-01  1.000e-09  1.000e-09  0.2500  0.000e+00  0.000e+00  0.000e+00  9.658e-02  7.372e-02  0.000e+00  0.000e+00\n",
      "   5  1.119e-01  0.000e+00  1.394e-01  2.787e-01  1.000e-09  1.000e-09  0.5000  0.000e+00  0.000e+00  0.000e+00  1.045e-01  5.785e-02  0.000e+00  0.000e+00\n",
      "   6  6.670e-02  0.000e+00  7.626e-02  1.525e-01  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  7.626e-02  4.524e-02  0.000e+00  0.000e+00\n",
      "   7  4.666e-02  0.000e+00  3.844e-02  7.687e-02  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  3.844e-02  2.004e-02  0.000e+00  0.000e+00\n",
      "   8  3.795e-02  0.000e+00  2.725e-02  5.450e-02  1.000e-09  1.000e-09  0.5000  0.000e+00  0.000e+00  0.000e+00  2.044e-02  8.713e-03  0.000e+00  0.000e+00\n",
      "   9  3.257e-02  0.000e+00  2.743e-02  5.486e-02  1.000e-09  1.000e-09  0.2500  0.000e+00  0.000e+00  0.000e+00  1.200e-02  5.380e-03  0.000e+00  0.000e+00\n",
      "iter    cost       merit      stop       grad       preg       dreg      step   ||ffeas||  ||gfeas||  ||hfeas||   dV-exp       dV      dPhi-exp     dPhi\n",
      "  10  2.829e-02  0.000e+00  2.687e-02  5.374e-02  1.000e-09  1.000e-09  0.2500  0.000e+00  0.000e+00  0.000e+00  1.176e-02  4.272e-03  0.000e+00  0.000e+00\n",
      "  11  2.340e-02  0.000e+00  2.508e-02  5.016e-02  1.000e-09  1.000e-09  0.2500  0.000e+00  0.000e+00  0.000e+00  1.097e-02  4.893e-03  0.000e+00  0.000e+00\n",
      "  12  2.013e-02  0.000e+00  2.042e-02  4.084e-02  1.000e-09  1.000e-09  0.5000  0.000e+00  0.000e+00  0.000e+00  1.532e-02  3.268e-03  0.000e+00  0.000e+00\n",
      "  13  6.083e-03  0.000e+00  1.646e-02  3.291e-02  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  1.646e-02  1.405e-02  0.000e+00  0.000e+00\n",
      "  14  3.911e-03  0.000e+00  2.237e-03  4.473e-03  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  2.237e-03  2.172e-03  0.000e+00  0.000e+00\n",
      "  15  3.894e-03  0.000e+00  2.398e-05  4.796e-05  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  2.398e-05  1.626e-05  0.000e+00  0.000e+00\n",
      "  16  3.892e-03  0.000e+00  3.794e-06  7.589e-06  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  3.794e-06  2.018e-06  0.000e+00  0.000e+00\n",
      "  17  3.892e-03  0.000e+00  8.709e-07  1.742e-06  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  8.709e-07  4.439e-07  0.000e+00  0.000e+00\n",
      "  18  3.892e-03  0.000e+00  2.134e-07  4.269e-07  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  2.134e-07  1.068e-07  0.000e+00  0.000e+00\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  19  3.892e-03  0.000e+00  5.366e-08  1.073e-07  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  5.366e-08  2.652e-08  0.000e+00  0.000e+00\n",
      "iter    cost       merit      stop       grad       preg       dreg      step   ||ffeas||  ||gfeas||  ||hfeas||   dV-exp       dV      dPhi-exp     dPhi\n",
      "  20  3.892e-03  0.000e+00  1.379e-08  2.758e-08  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  1.379e-08  6.771e-09  0.000e+00  0.000e+00\n",
      "  21  3.892e-03  0.000e+00  3.581e-09  7.162e-09  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  3.581e-09  1.750e-09  0.000e+00  0.000e+00\n",
      "  22  3.892e-03  0.000e+00  9.378e-10  1.876e-09  1.000e-09  1.000e-09  1.0000  0.000e+00  0.000e+00  0.000e+00  9.378e-10  4.570e-10  0.000e+00  0.000e+00\n"
     ]
    }
   ],
   "source": [
    "ddp.solve([],[],1000)  # xs_init,us_init,maxiter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can now look at the results, either in Gepetto-viewer by running the trajectory, or by plotting it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tp5.croco_utils as crocutils\n",
    "crocutils.displayTrajectory(viz,ddp.xs,ddp.problem.runningModels[0].dt,12)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And plotting..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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NUoYxLvf/W512WWXlZTNmzdPfelLXyqTRfsfO3bsUIB6+umnlVJKua6rWlpa1C233FJok06nVXV1tfrhD39YLjMnLfF4XB1yyCFq+fLl6rTTTlP/+q//qpSS+zxWfPGLX1Qnn3zysPVyn8eG8847T1100UUlZf/wD/+gLrjgAqVUee5zKpVSr732mkqlUuNy/nKwatUq1d3drR544AG1cOFCFQqFVENDg/r4xz+uurq6lFJKOY6jXnjhBbVjxw6llFKWZanVq1ernTt3Fs6TyWTUqlWrVG9vb6FsrO6XeFYGkM1mWbNmDYsXLy4pX7x4cckulMLeEY1GAairqwOgtbWVjo6OkvseCAQ47bTT5L7vAVdeeSXnnXceZ511Vkm53Oex4dFHH+XYY4/lYx/7GE1NTSxatIgf/ehHhXq5z2PDySefzJ///GfeeustAF566SWeffZZzj33XEDu81jy/PPP8+lPf5qLL76YF154gZtvvpl169bxmc98BvA2Da6srKSvrw+AZDKJUqpkE0m/308oFCq0GUtErAygq6sLx3Fobm4uKW9ubqajo6NMVu1fKKW49tprOfnkk1mwYAFA4d7Kfd97fvGLXxR+bAYi93ls2LBhA3feeSeHHHIIf/rTn7jsssu45ppr+N///V9A7vNY8cUvfpFPfOITzJs3D5/Px6JFi1i2bBmf+MQngIlzn5VSOE5ynwc1iu6Wzs5OWlpa+OY3v1koW7lyJX6/n+eff55Vq1Yxe/ZsrrnmGqZPn87RRx/NJZdcwurVqwvtTdMsbIZoWRaapmGapfsh+3w+bNveyzs6GNl1eRgG7oGglCrrvgj7E1dddRUvv/wyzz777KA6ue97x5YtW/jXf/1XnnjiiV0ubS33ee9wXZdjjz228MO/aNEiXn31Ve68804+/elPF9rJfd47HnzwQR544AF+9rOfccQRR7B27VqWLVvG1KlTufDCCwvtyn2fXTfFiqeP3GfXy3P6aeswjPCI2jY2NnLPPfewZMkSFi9ezLx587jgggu44ooreM973kNXVxff+MY3+MMf/sApp5zCzp07eeSRRzjvvPPG+VOMDPGsDKChoQHDMAap8h07dgxS78Loufrqq3n00Ud56qmnmD59eqG8paUFQO77XrJmzRp27NjBMcccg2mamKbJ008/ze23345pmoV7Kfd575gyZQrz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",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "log = ddp.getCallbacks()[0]\n",
    "crocoddyl.plotOCSolution(log.xs, log.us, figIndex=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## I. DifferentialActionModel for Pinocchio ABA\n",
    "ABA is a Rigid Body Algorithm optimized to calculate the acceleration in configuration space given the torque.\n",
    "\n",
    "This scenario uses an action model that computes 2nd order differential dynamics with Pinocchio. Note that it can accept several cost models. This action model is tailored for robot applications, and at the same time, it's modular since:\n",
    " - you can modify the robot dynamics by changing Pinocchio model, and\n",
    " - you can formulate any cost function by simply adding running and/or terminal costs.\n",
    "\n",
    " ABA是一种刚体算法，经过优化，可在给定扭矩的情况下计算构型空间中的加速度。\n",
    "\n",
    "此场景使用一种动作模型，该模型借助Pinocchio计算二阶微分动力学。请注意，它可以接受多种成本模型。这种动作模型专为机器人应用而定制，同时具有模块化特点，原因如下：\n",
    " - 你可以通过更改Pinocchio模型来修改机器人动力学，并且\n",
    " - 你只需添加运行成本和/或终端成本，就可以制定任何成本函数。 \n",
    "\n",
    "## II. Cost models\n",
    "\n",
    "A cost model computes a scalar cost value and its gradient and Hessian. All the models implemented are computing a cost residual and are computing the Hessian with the Gauss approximation.\n",
    "\n",
    "We implemented reusable cost models for controlling \n",
    " - a frame placement (translation or velocity),\n",
    " - the center of mass position, and \n",
    " - state  and control spaces.\n",
    "\n",
    "In the example above, we used the CostModelFrameTranslation which defines a 3d position task, and the state and control regularizers.\n",
    "\n",
    "成本模型计算一个标量成本值及其梯度和海森矩阵。所有已实现的模型都在计算成本残差，并使用高斯近似法计算海森矩阵。\n",
    "\n",
    "我们实现了可复用的成本模型，用于控制：\n",
    " - 帧的放置（平移或速度）\n",
    " - 质心位置\n",
    " - 状态空间和控制空间\n",
    "\n",
    "在上述示例中，我们使用了 `CostModelFrameTranslation`，它定义了一个三维位置任务，以及状态和控制正则化项。 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "All functions are defined by their *model*, which is const, i.e none of its fields is modified by the *calc* and *calcDiff* calls. Temporary buffers are defined in a companion *data*.\n",
    "\n",
    "所有函数都由其*模型*定义，该模型是常量，即其任何字段都不会被*calc*和*calcDiff*调用修改。临时缓冲区在配套的*data*中定义。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataCollector = crocoddyl.DataCollectorMultibody(robot.data)\n",
    "trackData = goalTrackingCost.createData(dataCollector)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### II.a Frame position cost\n",
    "\n",
    "You define a frame ID and the reference position as a 3D array. The cost is the distance between the frame and the target. This cost depends on $\\mathbf{x}$ (specifically the configuration $\\mathbf{q}$). You can double check the 0s in its gradient."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Lx =  [-0.07555753  0.03972517  0.13072172 -0.01393982 -0.01829586  0.05833534\n",
      "  0.          0.          0.          0.          0.          0.\n",
      "  0.          0.        ]\n",
      "Lu =  [0. 0. 0. 0. 0. 0. 0.]\n"
     ]
    }
   ],
   "source": [
    "x = ddp.xs[1].copy()\n",
    "q = x[:state.nq]\n",
    "pin.updateFramePlacements(robot.model, robot.data)\n",
    "pin.computeJointJacobians(robot.model, robot.data, q)\n",
    "goalTrackingCost.calc(trackData, x)\n",
    "goalTrackingCost.calcDiff(trackData, x)\n",
    "print('Lx = ',trackData.Lx) # For gradient\n",
    "print('Lu = ',trackData.Lu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### II.b State cost\n",
    "In this part of the tutorial you must define a State model. It defines \n",
    " - the dimension of the state and its tangent, and\n",
    " - the exponential/integrate and difference/log operators.\n",
    "The operators can described using Pinocchio functions. And the exercite consists on adding them into your State class. Please note crocoddyl has abstract functions for this.\n",
    "\n",
    "The state cost uses a reference in state space (State.zero() by default). The cost is the distance, computed with state.difference between the current state and the reference. Hence, with this cost, we regularize both position and velocity.\n",
    "\n",
    "### II.c Control cost\n",
    "\n",
    "The control cost uses a control reference as in the state cost. The cost is the distance the current control and the reference. Hence the cost regularizes torque commands."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### II.d Add cost models to the differential action model\n",
    "Each time we want to include a new cost function, we use addCost function inside our DAM. In this function you're also able its weight."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## III. Create the problem with integrated action model\n",
    "Differential action models describe cost and dynamics in continuous-time, however our optimal control solvers work in discrete-time. We have created the integrated action model in order to deal with this.\n",
    "\n",
    "In the previous code, we have used an abstract class that uses simpletic Euler rules. In the cartpole exercise you have learnt how to use integrated action models for your problem."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## IV. Callbacks\n",
    "\n",
    "Callback functions are needed for analysing and debugging the performance of the solver for your specific problem.\n",
    "For problems defined with Pinocchio, you can display the robot trajectory per each iterate by including CallbackDisplay. With this callback, you can display robot motions with different rates. Additionally, CallbackVerbose prints a message that allows us to understand the behaviour of the solver.\n",
    "\n",
    "Generally speaking, an user is able to describe any callback function. This function will be run once per iterate and it has access to all data."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## V. Modifying the example\n",
    "\n",
    "Start by defining several targets (let's say 4 targets, all at x=0.4, and at y and z being either 0 or 0.4), and display then in the viewer.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "viz.delete('world/goal')\n",
    "goals = np.array([\n",
    "    [.4, 0., 0.4],\n",
    "    [.4, 0., 0.],\n",
    "    [.4, 0.4, 0.4],\n",
    "    [.4, 0.4, 0.],\n",
    "])\n",
    "\n",
    "for i, g in enumerate(goals):\n",
    "    viz.addBox(f'world/goal{i}',[.1,.1,.1],[0,1,0,1])\n",
    "    viz.applyConfiguration(f'world/goal{i}',list(g) + [0,0,0,1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The shooting problem will be composed of 4 sequences of action models. Each sequence consists on T shooting \"running\" nodes and 1 terminal node. The running nodes mostly have regularization terms, while the terminal nodes have a strong cost toward the respective target.\n",
    "\n",
    "[ R1,R1,R1 ... R1,T1, R2,R2 .... R2, T2, R3 ... R3, T3, R4 ... R4 ] , T4\n",
    "\n",
    "First create 4 running models and 4 terminal models cost."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then you need to add a position cost, and state and control regularization to each running action model. Please  note that for terminal action model is only needed the position cost. Additionally, in the running models, the position cost should be low, and it should be high in the terminal models.\n",
    "Be carefull ! Intermediate terminal cost should not have $dt=0$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now create different shooting problem if you need to go through 1, 2, 3 or 4 positions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a DDP solver for this problem and run it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ddp = crocoddyl.SolverDDP(problem)\n",
    "ddp.solve()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Well, it should not work, at least no on the first shot. The DDP solver is likely not strong enough to accept the random weights that you have selected. \n",
    "\n",
    "If it is working nicely from the first shot, display it in the viewer and go take a coffee. But you will likely have to tweak the gains to make it work.\n",
    "\n",
    "**It is suggested to first optimize only sequence 1. When you are happy with it, add sequence 2 and optimize again, etc.**\n",
    "\n",
    "OCP allows to reduce the problem to a weight tunning one. However, some research try to automate this weight tunning part."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The solution if you need it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "%do_not_load tp5/generated/general_ddp_4stage"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "crocutils.displayTrajectory(viz, ddp.xs, ddp.problem.runningModels[0].dt, 12)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "robotics_course",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
